from typing import Optional, Sequence

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.depends import get_db, require_permission
from app.models.demo import PythonModel
from app.schemas.base_schema import ApiResult, PageResult, PageParam
from app.schemas.demo import PythonModelDTO, PythonModelSaveDTO, PythonModelUpdateDTO, PythonModelVO
from app.services.demo import PythonModelService
from app.utils.convert import pydantic_to_model

router = APIRouter(prefix="/model", tags=["python测试"])


@router.post(
    path="/page",
    summary="分页查询",
    dependencies=[Depends(require_permission("sys:user:view"))],
    response_model=ApiResult[PageResult[PythonModelVO]])
async def page(
    param: PageParam[PythonModelDTO],
    db: AsyncSession = Depends(get_db)
) -> ApiResult[PageResult[PythonModelVO]]:
    """
    分页查询

    :param param: 分页查询参数
    :param db: 数据库会话（依赖注入）
    :return: 分页查询结果
    """
    page_result: PageResult[PythonModelVO] = await PythonModelService.page(db, param)
    return ApiResult.ok(data=page_result)


@router.post(path="/list", summary="批量查询", response_model=ApiResult[Sequence[PythonModelVO]])
async def batch(param: PythonModelDTO, db: AsyncSession = Depends(get_db)) -> ApiResult[Sequence[PythonModelVO]]:
    """
    批量查询

    :param param: 查询条件参数
    :param db: 数据库会话（依赖注入）
    :return: 查询结果
    """
    # DTO -> Entity
    entity: PythonModel = pydantic_to_model(param, PythonModel)
    result: Sequence[PythonModelVO] = await PythonModelService.list(db, entity)
    return ApiResult.ok(data=result)


@router.get(
    path="/{id}",
    summary="单体查询",
    description="根据主键查询唯一数据，若查询不到则返回None",
    response_model=ApiResult[Optional[PythonModelVO]])
async def get(id: int, db: AsyncSession = Depends(get_db)) -> ApiResult[Optional[PythonModelVO]]:
    """
    单体查询
    根据主键查询唯一数据，若查询不到则返回null

    :param id: 主键
    :param db: 数据库会话（依赖注入）
    :return: 查询到的数据，未找到返回None
    """
    entity: Optional[PythonModelVO] = await PythonModelService.get(db, id)
    return ApiResult.ok(data=entity)


@router.post(path="", summary="新增", response_model=ApiResult[bool])
async def save(param: PythonModelSaveDTO, db: AsyncSession = Depends(get_db)) -> ApiResult[bool]:
    """
    新增

    :param param: 新增数据参数
    :param db: 数据库会话（依赖注入）
    :return:
    """
    # DTO -> Entity
    entity: PythonModel = pydantic_to_model(param, PythonModel)

    # 新增数据
    result: bool = await PythonModelService.save(db, entity)
    return ApiResult.ok(data=result) if result else ApiResult.fail(data=result)


@router.put(path="", summary="修改", response_model=ApiResult[bool])
async def update(param: PythonModelUpdateDTO, db: AsyncSession = Depends(get_db)) -> ApiResult[bool]:
    """
    修改

    :param param: 修改数据参数
    :param db: 数据库会话（依赖注入）
    :return:
    """
    # DTO -> Entity
    entity: PythonModel = pydantic_to_model(param, PythonModel)

    # 修改数据
    result: bool = await PythonModelService.update(db, entity)
    return ApiResult.ok(data=result) if result else ApiResult.fail(data=result)


@router.delete("/{id}", summary="单体删除", response_model=ApiResult[bool])
async def delete(id: int, db: AsyncSession = Depends(get_db)) -> ApiResult[bool]:
    """
    根据主键删除单条数据

    :param id: 主键
    :param db: 数据库会话（依赖注入）
    :return:
    """
    result: bool = await PythonModelService.delete(db, id)
    return ApiResult.ok(data=result) if result else ApiResult.fail(data=result)
